package com.tust.androidbbsclient.fragment;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ClipData;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

import androidx.activity.result.ActivityResult;
import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Base64;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.tust.androidbbsclient.R;
import com.tust.androidbbsclient.tool.Application;
import com.tust.androidbbsclient.tool.Tool;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.Objects;
//import java.util.Base64;

/**
 * A simple {@link Fragment} subclass.
 * Use the {@link SubmitFragment#newInstance} factory method to
 * create an instance of this fragment.
 */
public class SubmitFragment extends Fragment implements AdapterView.OnItemSelectedListener{
    private Toast toast;
    private Context context;
    private int UbanLevel;
    private String ArtCategory = null;
    private String ArtPic1 = null, ArtPic2 = null, ArtPic3 = null, ArtPic4 = null, ArtPic5 = null, ArtPic6 = null;

    //权限获取启动器
    ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), result -> {//注册权限获取启动器
        if (result.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) != null && result.get(Manifest.permission.READ_EXTERNAL_STORAGE) != null) {//检查是否已动态获取权限
            if (Objects.requireNonNull(result.get(Manifest.permission.WRITE_EXTERNAL_STORAGE)).equals(true) && Objects.requireNonNull(result.get(Manifest.permission.READ_EXTERNAL_STORAGE)).equals(true)) ;//showToast(Tool.addEmoji() + "读写权限获取成功！");
            else showToast(Tool.addEmoji() + "读写权限获取失败！");
            System.out.println("权限：文件读权限" + Objects.requireNonNull(result.get(Manifest.permission.WRITE_EXTERNAL_STORAGE)));
            System.out.println("权限：文件写权限" + Objects.requireNonNull(result.get(Manifest.permission.READ_EXTERNAL_STORAGE)));
        }
    });

    //活动结果启动器,用于返回文件选择器内容
    ActivityResultLauncher<Intent> activityResultLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
        @Override
        public void onActivityResult(ActivityResult result) {//活动结果启动器的回调方法
            TextView textViewSubmitImageInfo = getView().findViewById(R.id.tv_submit_imageInfo);

            //接收图片数据
            if (result.getResultCode() == Activity.RESULT_OK) {
                Intent data = result.getData();
                ClipData imageNames = data.getClipData();
                if (imageNames != null){
                    int imageCount = imageNames.getItemCount();
                    if (imageCount > 6) {
                        showToast(Tool.addEmoji() + "最大读取6张图片！");
                        imageCount = 6;
                    }

                    for (int i = 0; i < imageCount; i++) {
                        Uri imageUri = imageNames.getItemAt(i).getUri();

                        try (InputStream inputStream = context.getContentResolver().openInputStream(imageUri)) {
                            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                            byte[] buffer = new byte[1024];
                            int length;
                            while ((length = inputStream.read(buffer)) != -1) {
                                outputStream.write(buffer, 0, length);
                            }
                            byte[] imageBytes = outputStream.toByteArray();
                            byte[] encryptedBytes = Base64.encode(imageBytes, Base64.NO_WRAP | Base64.NO_PADDING | Base64.URL_SAFE);//android.util.Base64方法
                            /*byte[] encryptedBytes = new byte[0];
                            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {//java.util.Base64方法
                                encryptedBytes = Base64.getEncoder().encode(imageBytes);
                            }*/

                            String encryptedString = new String(encryptedBytes, StandardCharsets.UTF_8);

                            switch (i) {
                                case 0:
                                    ArtPic1 = encryptedString;
                                    break;
                                case 1:
                                    ArtPic2 = encryptedString;
                                    break;
                                case 2:
                                    ArtPic3 = encryptedString;
                                    break;
                                case 3:
                                    ArtPic4 = encryptedString;
                                    break;
                                case 4:
                                    ArtPic5 = encryptedString;
                                    break;
                                case 5:
                                    ArtPic6 = encryptedString;
                                    break;
                            }
                        } catch (IOException e) {
                            throw new RuntimeException(e);
                        }
                    }

                    textViewSubmitImageInfo.setText(String.format(Locale.CHINA, "已选择%1$d张图片!", imageCount));
                    //textViewSubmitImageInfo.setText("已选择" + imageCount + "张图片!");
                } else {
                    Uri imageUri = data.getData();

                    try (InputStream inputStream = context.getContentResolver().openInputStream(imageUri)) {
                        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                        byte[] buffer = new byte[1024];
                        int length;
                        while ((length = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, length);
                        }
                        byte[] imageBytes = outputStream.toByteArray();
                        byte[] encryptedBytes = Base64.encode(imageBytes, Base64.NO_WRAP | Base64.NO_PADDING | Base64.URL_SAFE);//android.util.Base64方法
                        /*byte[] encryptedBytes = new byte[0];
                        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {//java.util.Base64方法
                            encryptedBytes = Base64.getEncoder().encode(imageBytes);
                        }*/

                        ArtPic1 = new String(encryptedBytes, StandardCharsets.UTF_8);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                    textViewSubmitImageInfo.setText("已选择1张图片!");
                }
            }
        }
    });

    //用于在线程间传递消息
    @SuppressLint("HandlerLeak")
    private Handler handler = new Handler(Looper.myLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);//获取子线程传递的消息
            if (msg.what == 1) {//插入贴文请求返回值
                String strMsg = msg.obj.toString();
                //System.out.println("插入贴文：" + strMsg);

                switch (strMsg) {
                    case "serverFalse":
                        showToast(Tool.addEmoji() + "服务器通信失败！");
                        break;
                    case "userBaning":
                        showToast(Tool.addEmoji() + "您已被禁言！");
                        break;
                    case "insertArticleFalse":
                        showToast(Tool.addEmoji() + "贴文发布失败！");
                        break;
                    case "insertArticleSuccess":
                        showToast(Tool.addEmoji() + "贴文发布成功，等待审核！");
                        break;
                }
            }
        }
    };

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public SubmitFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment SubmitFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static SubmitFragment newInstance(String param1, String param2) {
        SubmitFragment fragment = new SubmitFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_submit, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        context = getContext();

        launcher.launch(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE});//调用启动器动态申请写入和读取存储权限

        EditText editTextSubmitArtTitle = view.findViewById(R.id.et_submit_artTitle);
        EditText editTextSubmitArtContent = view.findViewById(R.id.et_submit_artContent);
        ImageButton imageButtonSubmitArtPic = view.findViewById(R.id.ib_submit_artPic);
        Button buttonSubmitSubArticle = view.findViewById(R.id.btn_submit_subArticle);
        Spinner spinnerSubmitArtCategory = view.findViewById(R.id.spi_submit_artCategory);

        //从Application中获得用户信息
        Application application = (Application) getActivity().getApplication();
        UbanLevel = application.user.getUbanLevel();

        if (UbanLevel == -1) {//禁言状态
            //设置发布界面不可编辑
            buttonSubmitSubArticle.setText("您已被禁言！");
            editTextSubmitArtTitle.setFocusable(false);
            editTextSubmitArtTitle.setEnabled(false);
            editTextSubmitArtContent.setFocusable(false);
            editTextSubmitArtContent.setEnabled(false);
            spinnerSubmitArtCategory.setFocusable(false);
            spinnerSubmitArtCategory.setEnabled(false);
        }else spinnerSubmitArtCategory.setOnItemSelectedListener(this);

        //发布贴文按钮监听事件
        buttonSubmitSubArticle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (UbanLevel != -1) {//不是禁言状态
                    Application application = (Application) getActivity().getApplication();
                    int UID = application.user.getUID();
                    String ArtTitle = editTextSubmitArtTitle.getText().toString();
                    String ArtContent = editTextSubmitArtContent.getText().toString();

                    if (ArtTitle.equals("")) showToast(Tool.addEmoji() + "请输入贴文标题！");
                    else if (ArtContent.equals("")) showToast(Tool.addEmoji() + "请输入贴文内容！");
                    else if (Tool.StringLength(ArtTitle) > 200)  showToast(Tool.addEmoji() + "贴文标题小于200字符！");
                    else if (Tool.StringLength(ArtContent) > 2000)  showToast(Tool.addEmoji() + "贴文内容小于2000字符！");
                    else {
                        //发送插入贴文请求子线程
                        new Thread() {
                            @Override
                            public void run() {
                                OutputStream outputStream = null;
                                BufferedReader bufferedReader = null;
                                String data = "";
                                try {
                                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                    handlerMsg.what = 1;//增加handlerMsg标识符

                                    URL url = new URL(Tool.InetAddress + "/insertArticle.do");//请求地址
                                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                                    //连接类相关设置
                                    connection.setRequestMethod("POST");
                                    connection.setConnectTimeout(10000);//连接服务器超时
                                    connection.setReadTimeout(10000);//从服务器读取数据超时
                                    connection.setDoInput(true);//允许写入，从服务端读取结果流
                                    connection.setDoOutput(true);//允许写出，开启Post请求体
                                    connection.setUseCaches(false);//不使用Cache
                                    connection.setInstanceFollowRedirects(true);//自动处理重定向，成功获得200状态码
                                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");//设置http请求头格式
                                    connection.setRequestProperty("Connection", "Keep-Alive");//大数据保持连接

                                    connection.connect();//连接网络
                                    String params = "UID=" + UID + "&ArtCategory=" + ArtCategory + "&ArtTitle=" + ArtTitle + "&ArtContent=" + ArtContent + "&ArtPic1=" + ArtPic1 + "&ArtPic2=" + ArtPic2 + "&ArtPic3=" + ArtPic3 + "&ArtPic4=" + ArtPic4 + "&ArtPic5=" + ArtPic5 + "&ArtPic6=" + ArtPic6;//请求体内容
                                    outputStream = connection.getOutputStream();//请求输出流
                                    outputStream.write(params.getBytes());

                                    int code = connection.getResponseCode();//获得响应状态码
                                    if (code == 200) {//返回状态码200，连接成功
                                        bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                                        data = bufferedReader.readLine();

                                        handlerMsg.obj = data;//写入线程传递消息
                                    } else handlerMsg.obj = "serverFalse";//服务器通信失败
                                    connection.disconnect();//关闭连接

                                    handler.sendMessage(handlerMsg);//发送线程消息
                                } catch (IOException e) {
                                    Message handlerMsg = Message.obtain();//构造Message对象，用于向主线程传递消息
                                    handlerMsg.what = 1;//增加handlerMsg标识符
                                    handlerMsg.obj = "serverFalse";
                                    handler.sendMessage(handlerMsg);

                                    //throw new RuntimeException(e);
                                } finally {
                                    try {
                                        if (bufferedReader != null) bufferedReader.close();
                                        if (outputStream != null) {
                                            outputStream.flush();
                                            outputStream.close();
                                        }
                                    } catch (IOException e) {
                                        System.out.println("子线程：finally失败");
                                        //throw new RuntimeException(e);
                                    }
                                }
                            }
                        }.start();
                        editTextSubmitArtTitle.setText("");
                        editTextSubmitArtContent.setText("");
                    }
                }
            }
        });

        //发布贴文图片按钮监听事件
        imageButtonSubmitArtPic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (UbanLevel != -1) {//不是禁言状态
                    //跳转到文件选择器
                    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
                    intent.setType("image/jpeg");//筛选器
                    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);

                    activityResultLauncher.launch(Intent.createChooser(intent, "选择贴文图片"));
                }
            }
        });
    }

    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
        String[] categories = getResources().getStringArray(R.array.categories);
        ArtCategory = categories[i];
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {

    }

    private void showToast(String s) {
        if (toast == null){
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
        }else {
            toast.cancel();
            toast = Toast.makeText(context, s, Toast.LENGTH_SHORT);
        }
        toast.show();
    }
}
